package com.gp.framework.proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 日志拦截器
 *
 * @author
 * @create 2017-06-21
 */
public class LogInterceptor implements MethodInterceptor {
    private static final Logger LOGGER = LogManager.getLogger(LogInterceptor.class);
    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss");

    public Object getInstance(Class clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        Object proxyObj = enhancer.create();
        LOGGER.debug("LogInterceptor {}", proxyObj.getClass());
        return proxyObj;
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object result = methodProxy.invokeSuper(obj, args);
        printLog(obj, method, args, result);
        return result;
    }

    //日志要求按天存储、日志内容包含时间戳，类名，方法名，参数列表，参数值，返回值
    private void printLog(Object obj, Method method, Object[] args, Object result) throws Exception {
        StringBuilder logBuilder = new StringBuilder("时间戳：");

        StringBuilder paramsBuilder = new StringBuilder();
        Class<?>[] paramTypes = method.getParameterTypes();
        for (int i = 0; i < paramTypes.length; i++) {
            paramsBuilder.append(paramTypes[i].getName()).append(" ").append(args[i]).append(",");
        }
        if (paramsBuilder.length() > 0)
            paramsBuilder.deleteCharAt(paramsBuilder.length() - 1);

        logBuilder.append(dateFormat.format(new Date()));
        logBuilder.append(" 方法签名：");
        logBuilder.append(obj.getClass().getSuperclass().getName());
        logBuilder.append(".");
        logBuilder.append(method.getName());
        logBuilder.append("(");
        logBuilder.append(paramsBuilder.toString());
        logBuilder.append(")");
        Class<?> returnType = method.getReturnType();
        if (void.class == returnType) {
            logBuilder.append(" 返回值类型：");
            logBuilder.append(returnType.getName());
            logBuilder.append(" 返回值：");
            logBuilder.append("null");
        } else {
            logBuilder.append(" 返回值类型：");
            logBuilder.append(result.getClass().getName());
            logBuilder.append(" 返回值：");
            logBuilder.append(result);
        }
        LOGGER.info("{}", logBuilder.toString());
    }
}
